package chatsystem.ni;

import chatsystem.FileTransferStatusCB;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;

/** Ce thread s'occupe de l'envoi synchrone d'un fichier sur TCP. */
public class FileSender extends Thread 
{
   public FileSender(ChatNI owner, InputStream file, InetAddress peer, 
                     FileTransferStatusCB cb)
   {
      _owner = owner;
      _file = file;
      _addr = peer;
      _cb = cb;
      _cancelled = false;
   }
   
   /** Annulation en cours de transfert. */
   public void stopSend()
   {
      // thread will exit on error, or already finished.
      try {_sock.close();} catch (Throwable e) {}
   }
   
   /** Si annulation AVANT le début du tranfert. */
   public void cancel()
   {
      _cb.onError("Cancelled");
      // Assuming Threads can't be deleted before they are started without problems.
      _cancelled = true;
      start();
   }
   
   public void run()
   {
      if (_cancelled)
         return;
      
      _sock = null;
      try {
         
         _sock = new java.net.Socket(_addr, 16050);
         _cb.onStart();
         
         OutputStream o = _sock.getOutputStream();
         int c;
         
         // Mauvaises perfs. Faudrait déplacer des blocs de 4Ko ou utiliser les
         // BufferedReader/Writer.
         while ((c = _file.read()) != -1)
            o.write(c);
         
         _cb.onFinish();
      } 
      catch (IOException ex) {
         _cb.onError("Net/IO error");
      } 
      finally {
         if (_sock != null)
            try {_sock.close(); _file.close();} catch(Throwable e){}
         _owner.onFileTransferEnd();
      }
      
   }
   
   private ChatNI _owner;
   private boolean _cancelled;
   private InputStream _file;
   private InetAddress _addr;
   private FileTransferStatusCB _cb;
   private java.net.Socket _sock;
}
